package com.demo.util.excel.utils;

import com.demo.util.CharUtil;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Font;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;

import java.util.Arrays;

public class ExcelWidthUtil {

    /** 默认字体大小 */
    private static final int DEFAULT_FONT_SIZE = 200;

    /** 最小宽度 */
    private static final int MIN_WIDTH = 1000;

    /** 最大宽度 */
    private static final int MAX_WIDTH = 256 * 255;


    public static void setColumnAutoSize(Sheet sheet, int lastHeaderIndex, int rowSize) {
        int maxRowIndex = lastHeaderIndex + rowSize;
        sheet.forEach(row -> {
            int rowNum = row.getRowNum();
            if (rowNum < lastHeaderIndex || rowNum > maxRowIndex) {
                return;
            }
            row.forEach(cell -> {
                int colIndex = cell.getColumnIndex();
                int oldWidth = sheet.getColumnWidth(colIndex);
                int newWidth = getCellWidth(cell, oldWidth);
                sheet.setColumnWidth(colIndex, newWidth);
            });
        });
    }

    private static int getCellWidth(Cell cell, int oldWidth) {
        int fontSize = getCellFontSize(cell);
        int textWidth = getCellTextWidth(cell);
        int cellWidth = textWidth * fontSize / DEFAULT_FONT_SIZE;
        int newWidth = Math.max(oldWidth, cellWidth);
        newWidth = Math.max(newWidth, MIN_WIDTH);
        newWidth = Math.min(newWidth, MAX_WIDTH);
        return newWidth;
    }

    private static short getCellFontSize(Cell cell) {
        Sheet sheet = cell.getSheet();
        Workbook workbook = sheet.getWorkbook();
        int fontIndex = cell.getCellStyle().getFontIndexAsInt();
        Font font = workbook.getFontAt(fontIndex);
        return font.getFontHeight();
    }

    private static int getCellTextWidth(Cell cell) {
        String cellValue = ExcelCellValueUtil.getCellStringValue(cell);
        if (StringUtils.isBlank(cellValue)) {
            return 0;
        }
        return Arrays.stream(cellValue.split("(\\n|\\r\\n)"))
                .mapToInt(ExcelWidthUtil::getTextWidth)
                .max()
                .getAsInt();
    }

    private static int getTextWidth(String rowText) {
        return rowText
                .chars()
                .map(charCode -> {
                    boolean isChineseChar = CharUtil.isChineseChar(charCode);
                    if (isChineseChar) {
                        return 2 * 0x100;
                    }
                    return 0x100;
                })
                .sum();
    }

}
